/*
    消息处理中心接口
    BaseMessage: 发送消息基类
    BaseHandle：接受消息基类

    使用只需要使用这两个基类即可
 */


#ifndef __CENTER_H__
#define __CENTER_H__


#include <iostream>
#include <string>
#if defined(_WIN32)
#include <Windows.h>
#endif
#include "df.h"
#include "mgnotify.h"

template <typename M>
class BaseMessage;
template <typename M>
class BaseHandle;

class IHandle
{
public:
    virtual std::string getType() = 0;
    virtual ~IHandle() {};
};

class IMessage
{
public:
    virtual bool send(IHandle *handle) const = 0;
    virtual ~IMessage() {};
};

template <typename M>
class BaseMessage : public IMessage
{
public:
    BaseMessage() {}
    virtual ~BaseMessage() {}

    virtual bool send() const;
    virtual void post(MessagePriority priority = MP_COMMON) const;

private:
    virtual bool send(IHandle *handle) const;
};

template <typename M>
bool BaseMessage<M>::send() const
{
    return mgnotify::getInstance()->sendMessage(this);
}

template <typename M>
void BaseMessage<M>::post(MessagePriority priority) const
{
    auto t = new M(*((M*)this));
    mgnotify::getInstance()->pushMessage(t, priority);
}

template <typename M>
bool BaseMessage<M>::send(IHandle *handle) const
{
    if(handle == nullptr) {
#if defined(_WIN32)
        OutputDebugStringA("invalid receiver");
#else
        perror("invalid receiver");
#endif
        return false;
    }
    BaseHandle<M> *t = dynamic_cast<BaseHandle<M>*>(handle);
    if(t == nullptr) {
#if defined(_WIN32)
        OutputDebugStringA("invalid base receiver");
#else
        perror("invalid base receiver");
#endif
        return false;
    }
    return t->handle((const M*)this);
}

template <typename M>
class BaseHandle : public IHandle
{
public:
    BaseHandle() { mgnotify::getInstance()->attach(this); };
    virtual ~BaseHandle() { mgnotify::getInstance()->detach(this); };

    virtual std::string getType() final;
    virtual bool handle(const M* msg) = 0;
};

template <typename M>
std::string BaseHandle<M>::getType()
{
    return typeid(M).name();
}

#endif // __CENTER_H__